/*
 * The MIT License (MIT)
 * Copyright © 2022 Walkline Wang (https://walkline.wang)
 * Gitee: https://gitee.com/walkline/ramcu-mechanical-keypad
 */
#include "app_common.h"
#include "key_matrix.h"
#include "keycode.h"

/**
 * 私有函数
 **/
static void update_keycode_list(uint8_t last_keycode, bool pressed);

/**
 * 私有常量
 **/
/* 小键盘行线引脚 */
static const int io_key_rows[] = {
	io_key_row_1,
	io_key_row_2,
	io_key_row_3,
	io_key_row_4,
	io_key_row_5
};

/* 小键盘列线引脚 */
static const int io_key_cols[] = {
	io_key_col_1,
	io_key_col_2,
	io_key_col_3,
	io_key_col_4
};

/* 小键盘对应键码表 */
static const uint8_t keycode_matrix[ROW_COUNT][COL_COUNT] = {
	{NUM_LOCK, SLASH, ASTERISK, MINUS},
	{HOME_7, UP_8, PGUP_9, PLUS},
	{LEFT_4, FIVE, RIGHT_6},
	{END_1, DOWN_2, PGDN_3, ENTER},
	{INS_0, DEL_DOT}
};

/**
 * 私有变量
 **/
static volatile uint8_t last_key_status_table[ROW_COUNT][COL_COUNT] = {0};

/**
 * 全局变量
 **/
volatile uint8_t g_normal_keycode_list[6] = {0};
volatile bool g_keycode_changed = false;

//static uint8_t press_a[] = {0x57, 0xab, 0x00, 0x02, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
//static uint8_t release_a[] = {0x57, 0xab, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c};

void matrix_scan()
{
	bsp_io_level_t col_value1, col_value2;

	for (int row=0; row<ROW_COUNT; row++) {
		// 所有行拉低
		for (int index=0; index<ROW_COUNT; index++) {
			set_io_low(io_key_rows[index]);
		}

		// 逐行拉高
		set_io_high(io_key_rows[row]);

		//检查本行所有列的值，并记录发生改变的按键坐标
		for (int col=0; col< COL_COUNT; col++) {
			//软件消抖
			read_io(io_key_cols[col], col_value1);
			sleep_ms(1);
			read_io(io_key_cols[col], col_value2);

			if (col_value1 != col_value2) {continue;}

			if (last_key_status_table[row][col] != col_value1) {
#if DEBUG
				printf("key(%d, %d) status: %d", row, col, col_value1);
#endif

				//有按键按下
				if (col_value1 == 1) {
#if 0
					//ASCII 模式下发送字符
					R_SCI_UART_Write(&g_uart_usb_hid_ctrl, (uint8_t *)"A", 1);
#endif

					update_keycode_list(keycode_matrix[row][col], true);
				} else { //有按键释放
					update_keycode_list(keycode_matrix[row][col], false);
				}

				last_key_status_table[row][col] = col_value1;
			}
		}
	}
}

/* 维护待发送键码列表，更新按键按下或释放状态 */
static void update_keycode_list(uint8_t last_keycode, bool pressed)
{
	int zero_pos = -1;
	int keycode_pos = -1;

	for (int i=0; i<6; i++) {
		if (g_normal_keycode_list[i] == 0 && zero_pos == -1) {
			zero_pos = i;
		}

		if (g_normal_keycode_list[i] == last_keycode) {
			keycode_pos = i;
			break;
		}
	}

	if (pressed) {
		if (zero_pos != -1 && keycode_pos == -1) {
			g_normal_keycode_list[zero_pos] = last_keycode;
			g_keycode_changed = true;
		} else {
			g_keycode_changed = false;
		}
	} else {
		if (keycode_pos != -1) {
			g_normal_keycode_list[keycode_pos] = 0;
			g_keycode_changed = true;
		} else {
			g_keycode_changed = false;
		}
	}
}
